package com.lysj.food.food.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.lysj.admin.common.food.domain.OrderItemVo;
import com.lysj.admin.common.food.domain.OrderVo;
import com.lysj.admin.common.order.domain.OrderItemAndFoodWeight;
import com.lysj.admin.common.order.domain.OrderModifyVo;
import com.lysj.admin.utils.constant.CommonConstant;
import com.lysj.admin.utils.exception.BaseException;
import com.lysj.admin.utils.json.JacksonUtil;
import com.lysj.admin.utils.spring.foundation.base.BaseService;
import com.lysj.admin.utils.spring.foundation.pagination.PageUtil;
import com.lysj.admin.utils.spring.foundation.pagination.PageVo;
import com.lysj.admin.utils.web.ParamUtil;
import com.lysj.admin.utils.web.Resp;
import com.lysj.food.food.domain.*;
import com.lysj.food.food.dto.FoodAndCount;
import com.lysj.food.food.dto.OrderAddDto;
import com.lysj.food.food.feign.DeskFeign;
import com.lysj.food.food.feign.OrderFeign;
import com.lysj.food.food.repository.FoodRepository;
import com.lysj.food.food.vo.BackGroundFoodVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Created by wtl on 2019-03-19 16:00:45
 * @description 菜品服务层
 */
@Slf4j
@Service
@Transactional
public class FoodService implements BaseService<Food> {

    @Resource
    private FoodRepository foodRepository;

    @Override
    public FoodRepository getRepository() {
        return foodRepository;
    }

    @Resource
    private FoodTypeService foodTypeService;

    @Resource
    private DeskFeign deskFeign;
    @Resource
    private DefaultFoodService defaultFoodService;
    @Resource
    private WeighFoodService weighFoodService;
    @Resource
    private OrderFeign orderFeign;

    @Resource
    private FoodGuigeService foodGuigeService;

    @Resource
    private FoodAttributeDetailService foodAttributeDetailService;

    /**
     * @author Created by wtl on 2019/4/16 16:55
     * @Description 获取规格填充菜品
     */
    public void findFoodGuiGe(String storeId, List<BackGroundFoodVo> backGroundFoodVos) {
        //获取规格信息
        Map<String, String> guiGeMap = foodAttributeDetailService.map(storeId);
        for (BackGroundFoodVo backGroundFoodVo : backGroundFoodVos) {
            List<FoodGuiGe> foodGuiGeList = foodGuigeService.getRepository().findByFoodIdAndDelFlag(backGroundFoodVo.getFoodId(), CommonConstant.NORMAL_FLAG);
            for (FoodGuiGe foodGuiGe : foodGuiGeList) {
                foodGuiGe.setName(guiGeMap.get(foodGuiGe.getFoodAttributeDetailId()));
            }
            backGroundFoodVo.setFoodGuiGeList(foodGuiGeList);
        }
    }

    /**
     * @author Created by wtl on 2019/4/2 16:25
     * @Description 获取门店的菜品类型以及第一个菜品类型对应的菜品列表
     */
    public Map<String, Object> getStoreFoodList(String storeId) {
        if (ParamUtil.isBlank(storeId)) {
            throw new BaseException("参数错误，门店不能为空");
        }
        // 根据门店id查询出门店对应的菜品类型
        List<FoodType> foodTypes = foodTypeService.findByStoreId(storeId);
        // 第一个菜品类型对应的菜品
        List<BackGroundFoodVo> backGroundFoodVos = new ArrayList<>();
        // 根据菜品类型id查询第一个菜品类型对应的菜品列表
        if (!foodTypes.isEmpty()) {
            backGroundFoodVos = getRepository().findFoodListByFoodTypeId(foodTypes.get(0).getId());
        }
        // 填充菜品的规格
        findFoodGuiGe(storeId, backGroundFoodVos);
        Map<String, Object> map = new HashMap<>();
        map.put("foodTypes", foodTypes);
        map.put("foods", backGroundFoodVos);
        return map;
    }

    /**
     * @param foodTypeId 菜品类型id列表
     * @author Created by wtl on 2019/3/26 17:28
     * @Description 通过菜品类型id查询菜品
     */
    public List<BackGroundFoodVo> findByFoodTypeId(String foodTypeId) {
        List<BackGroundFoodVo> backGroundFoodVos = getRepository().findFoodListByFoodTypeId(foodTypeId);
        // 需要一个门店id
        FoodType foodType = foodTypeService.findOne(foodTypeId);
        // 填充规格
        if (ParamUtil.isBlank(foodType.getStoreId())) {
            throw new BaseException("门店id有误");
        }
        findFoodGuiGe(foodType.getStoreId(), backGroundFoodVos);
        return backGroundFoodVos;
    }

    /**
     * @author Created by wtl on 2019/3/27 15:07
     * @Description 获取本门店还未设置为默认下单的菜品
     */
    public Page<Food> findNotDefaultFood(String storeId, PageVo pageVo) {
        Pageable pageable = PageUtil.initPage(pageVo);
        return foodRepository.findNotDefaultFood(storeId, pageable);
    }

    /**
     * 将菜品信息填充到orderItemVo
     *
     * @param count   菜品数量
     * @param guiGeId 规格id
     */
    public OrderItemVo food2OrderItem(Food food, Integer count, String guiGeId) {
        OrderItemVo orderItemVo = new OrderItemVo();
        orderItemVo.setFoodId(food.getId());
        orderItemVo.setName(food.getName());
        orderItemVo.setAmount(count);
        orderItemVo.setDoWay("做法");
        // 多规格的菜品
        if (!ParamUtil.isBlank(guiGeId)) {
            //获取规格信息
            Map<String, String> guiGeMap = foodAttributeDetailService.map(food.getStoreId());
            // 从规格表获取价格
            orderItemVo.setSpecifications(guiGeMap.get(guiGeId));
            // 菜品价格，
            orderItemVo.setUnitPrice(foodGuigeService.findOne(guiGeId).getSellFee());
        } else {
            // 单规格的菜品，根据菜品id获取规格
            orderItemVo.setUnitPrice(foodGuigeService.getRepository().findByFoodIdAndDelFlag(food.getId(), 1).get(0).getSellFee());
        }
        // 总价
        orderItemVo.setTolPrice(orderItemVo.getUnitPrice().multiply(new BigDecimal(count)));
        orderItemVo.setStatus(1); // 点菜
        // 需要称重
        if (!ParamUtil.isBlank(food.getChengZhongIds())) {
            WeighFood model = new WeighFood();
//            model.setUnitPrice(food.getSellFee());
            model.setType(1); // 待称重
            WeighFood weighFood = weighFoodService.save(model);
            orderItemVo.setWeighFoodId(weighFood.getId());
        }
        return orderItemVo;
    }

    /**
     * 点菜时添加默认菜品
     */
    public void addDefaultFood(List<OrderItemVo> orderItemVos, String storeId) {
        // 获取默认本店的默认菜品
        List<DefaultFood> defaultFoods = defaultFoodService.findByStoreId(storeId);
        for (DefaultFood defaultFood : defaultFoods) {
            Food food = findOne(defaultFood.getFoodId());
            orderItemVos.add(food2OrderItem(food, defaultFood.getCount(), null));
        }
    }


    /**
     * 点菜时添加茶座费
     */
    public void addTeaFee(List<OrderItemVo> orderItemVos, String storeId) {
        // 获取茶座费
        BigDecimal teaCharge = deskFeign.getStoreTeaCharge(storeId);
        OrderItemVo teaItem = new OrderItemVo();
        teaItem.setName("茶座费");
        teaItem.setAmount(1);
        teaItem.setUnitPrice(teaCharge);
        teaItem.setTolPrice(teaCharge);
        teaItem.setStatus(4); // 茶座费
        orderItemVos.add(teaItem);
    }

    /**
     * @author Created by wtl on 2019/4/1 15:12
     * @Description 点菜并远程调用下单接口
     */
    public String createOrder(OrderAddDto orderAddDto) {

        List<OrderItemVo> orderItemVos = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        // 解析前端的json字符串
        List<FoodAndCount> foodAndCounts = JacksonUtil.toList(orderAddDto.getFoodAndCounts(), FoodAndCount.class);
        if (foodAndCounts.size() < 1) {
            throw new BaseException("请选择菜品下单",Resp.Status.PARAM_ERROR.getCode());
        }
        // 获取菜品详情
        for (FoodAndCount foodAndCount : foodAndCounts) {
            ids.add(foodAndCount.getFoodId());
        }
        List<Food> foods = foodRepository.findAll(ids);
        for (int i = 0; i < foods.size(); i++) {
            Food food = foods.get(i);
            Integer count = foodAndCounts.get(i).getCount();
            String guiGeId = foodAndCounts.get(i).getGuiGeId(); // 规格id，多规格菜品才有
            // 先判断库存
            if (food.getInventory() < count) {
                throw new BaseException("库存不足", Resp.Status.PARAM_ERROR.getCode());
            }
            // 减库存
            food.setInventory(food.getInventory() - count);
            // 添加点的菜品
            orderItemVos.add(food2OrderItem(food, count, guiGeId));
        }
        // 保存库存
        foodRepository.save(foods);
        // 添加默认菜品
        addDefaultFood(orderItemVos, orderAddDto.getStoreId());
        // 添加茶座费
//        addTeaFee(orderItemVos, orderAddDto.getStoreId());

        OrderVo orderVo = new OrderVo();
        orderVo.setStoreId(orderAddDto.getStoreId());
        orderVo.setDeskId(orderAddDto.getDeskId());
        orderVo.setCusAmount(orderAddDto.getCusAmount());
        orderVo.setCustomerId(orderAddDto.getCustomerId());
        orderVo.setOrderItemList(orderItemVos);

        // 调用创建订单feign
        Map<String, Object> map = orderFeign.createOrder(orderVo);
        List<OrderItemAndFoodWeight> orderItemAndFoodWeights = (List<OrderItemAndFoodWeight>) map.get("orderItemAndFoodWeightList");
        for (OrderItemAndFoodWeight orderItemAndFoodWeight : orderItemAndFoodWeights) {
            WeighFood weighFood = weighFoodService.findOne(orderItemAndFoodWeight.getWeighFoodId());
            weighFood.setOrderItemId(orderItemAndFoodWeight.getOrderItemId());
            weighFood.setStoreId(orderAddDto.getStoreId());
            weighFoodService.save(weighFood);
        }
        return (String) map.get("orderId");
    }


    /**
     * @author Created by wtl on 2019/3/29 19:10
     * @Description 加菜业务，调用修改订单feign
     */
    public String orderModify(String orderId, String foodAndCounts) {
        if (ParamUtil.isBlank(foodAndCounts)) {
            foodAndCounts = "[{\"foodId\":\"123264543739613184\",\"count\":1,\"guiGeId\":\"123545564\"}]";
        }
        List<OrderItemVo> orderItemVos = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        List<FoodAndCount> foodAndCountList = JacksonUtil.toList(foodAndCounts, FoodAndCount.class);
        // 获取菜品详情
        for (FoodAndCount foodAndCount : foodAndCountList) {
            ids.add(foodAndCount.getFoodId());
        }
        List<Food> foods = foodRepository.findAll(ids);
        for (int i = 0; i < foods.size(); i++) {
            Food food = foods.get(i);
            int count = foodAndCountList.get(i).getCount();
            String guiGeId = foodAndCountList.get(i).getGuiGeId(); // 规格id，多规格菜品才有
            // 先判断库存
            if (food.getInventory() < count) {
                throw new BaseException("库存不足");
            }
            // 减库存
            food.setInventory(food.getInventory() - count);
            // 添加点的菜品
            orderItemVos.add(food2OrderItem(food, count, guiGeId));
        }
        OrderModifyVo orderModifyVo = new OrderModifyVo();
        orderModifyVo.setOrderId(orderId);
        orderModifyVo.setOrderItemList(orderItemVos);
        // 调用修改订单feign
        List<OrderItemAndFoodWeight> orderItemAndFoodWeights = orderFeign.orderModify(orderModifyVo);
        for (OrderItemAndFoodWeight orderItemAndFoodWeight : orderItemAndFoodWeights) {
            WeighFood weighFood = weighFoodService.findOne(orderItemAndFoodWeight.getWeighFoodId());
            weighFood.setOrderItemId(orderItemAndFoodWeight.getOrderItemId());
            weighFoodService.save(weighFood);
        }
        return orderId;
    }


    /**
     * @author Created by wtl on 2019/4/2 15:55
     * @Description 称重业务，将待称重的改成已称重
     */
    public boolean orderItemModify(String weighFoodId, String weight) {
        WeighFood weighFood = weighFoodService.findOne(weighFoodId);
        if (ParamUtil.isBlank(weighFood)) {
            throw new BaseException("未找到称重记录", Resp.Status.PARAM_ERROR.getCode());
        }
        weighFood.setWeight(weight);
        weighFood.setType(2); // 已称重
        weighFoodService.save(weighFood);
        // 计算总价
        BigDecimal tolPrice = weighFood.getUnitPrice().multiply(new BigDecimal(weight));
        // 远程调用修改orderItem
        boolean flag = orderFeign.orderIemModify(weighFood.getOrderItemId(), tolPrice, weight);
        return flag;
    }


    @Override
    public Food save(Food entity) {
        entity = foodRepository.save(entity);
        List<FoodGuiGe> foodGuiGes = JacksonUtil.toList(entity.getFoodGuiges(), FoodGuiGe.class);
        // 保存菜品规格列表
        for (FoodGuiGe foodGuiGe : foodGuiGes) {
            foodGuiGe.setFoodId(entity.getId());
        }
        foodGuigeService.save(foodGuiGes);
        return entity;
    }


    @Override
    public Food update(Food entity) {
        Food food = foodRepository.findOne(entity.getId());
        CopyOptions copyOptions = CopyOptions.create();
        copyOptions.setIgnoreNullValue(true);
        BeanUtil.copyProperties(entity, food, copyOptions);
        //清除foodid对应的规格列表
        List<FoodGuiGe> foodGuiGeList = foodGuigeService.getRepository().findByFoodIdAndDelFlag(entity.getId(), CommonConstant.NORMAL_FLAG);
        for (FoodGuiGe foodGuiGe : foodGuiGeList) {
            foodGuiGe.setDelFlag(CommonConstant.DEL_FLAG);
        }
        foodGuigeService.save(foodGuiGeList);
        List<FoodGuiGe> foodGuiGes = JacksonUtil.toList(entity.getFoodGuiges(), FoodGuiGe.class);
        // 保存菜品规格列表
        for (FoodGuiGe foodGuiGe : foodGuiGes) {
            foodGuiGe.setFoodId(entity.getId());
        }
        foodGuigeService.save(foodGuiGes);
        return food;
    }
}